use std::sync::Arc;
use anyhow::Result;
use halo_model::{ExtensionOperator, GVK};

use crate::config::app_error::AppResult;
use crate::extension::index::scheme_manager::SchemeManager;
use crate::di::app_container::AppContainer;
use crate::get_scheme_manager;

/// 示例：如何使用修改后的 SchemeManager
/// 
/// 这个示例展示了如何在依赖注入框架中使用支持内部可变性的 SchemeManager
pub struct SchemeManagerUsageExample;

impl SchemeManagerUsageExample {
    /// 示例1：通过依赖注入获取 SchemeManager 并注册 scheme
    pub async fn register_scheme_example<T>() -> AppResult<()>
    where
        T: ExtensionOperator + GVK,
    {
        // 从依赖注入容器获取 SchemeManager
        // 返回的是 Arc<SchemeManager>，但由于内部使用了 RwLock，
        // 我们可以在不需要 &mut self 的情况下进行可变操作
        let scheme_manager: Arc<SchemeManager> = get_scheme_manager!()?;
        
        // 注册 scheme - 注意这里不需要 &mut，因为内部使用了 RwLock
        scheme_manager.register::<T>().await?;
        
        println!("Successfully registered scheme for type: {}", std::any::type_name::<T>());
        
        Ok(())
    }
    
    /// 示例2：使用 register_fun 方法注册带有自定义逻辑的 scheme
    pub async fn register_scheme_with_function_example<T>() -> AppResult<()>
    where
        T: ExtensionOperator + GVK,
    {
        let scheme_manager = get_scheme_manager!()?;
        
        // 使用 register_fun 方法，传入自定义的处理函数
        scheme_manager.register_fun::<_, T>(|index_specs| {
            // 在这里可以对 index_specs 进行自定义配置
            println!("Configuring index specs for type: {}", std::any::type_name::<T>());
            Ok(())
        }).await?;
        
        Ok(())
    }
    
    /// 示例3：查询已注册的 scheme
    pub async fn query_scheme_example<T>() -> AppResult<()>
    where
        T: GVK,
    {
        let scheme_manager = get_scheme_manager!()?;
        
        // 根据类型获取 scheme
        match scheme_manager.get_by_type::<T>().await {
            Ok(scheme) => {
                println!("Found scheme: {:?}", scheme);
                
                // 获取所有已注册的 schemes
                let all_schemes = scheme_manager.schemes()?;
                println!("Total registered schemes: {}", all_schemes.len());
                
                // 获取 schemes 数量
                let count = scheme_manager.size()?;
                println!("Scheme count: {}", count);
            }
            Err(e) => {
                println!("Scheme not found for type {}: {:?}", std::any::type_name::<T>(), e);
            }
        }
        
        Ok(())
    }
    
    /// 示例4：在多线程环境中使用 SchemeManager
    pub async fn concurrent_usage_example<T>() -> AppResult<()>
    where
        T: ExtensionOperator + GVK + Send + Sync + 'static,
    {
        let scheme_manager = get_scheme_manager!()?;
        
        // 创建多个任务并发访问 SchemeManager
        let mut handles = vec![];
        
        for i in 0..5 {
            let manager = Arc::clone(&scheme_manager);
            let handle = tokio::spawn(async move {
                // 每个任务都可以安全地访问 SchemeManager
                let result = manager.register::<T>().await;
                println!("Task {} completed with result: {:?}", i, result);
                result
            });
            handles.push(handle);
        }
        
        // 等待所有任务完成
        for handle in handles {
            handle.await.map_err(|e| {
                crate::config::app_error::AppError::InternalServerError(
                    format!("Task failed: {}", e)
                )
            })??;
        }
        
        println!("All concurrent tasks completed successfully");
        Ok(())
    }
    
    /// 示例5：错误处理
    pub async fn error_handling_example() -> AppResult<()> {
        let scheme_manager = get_scheme_manager!()?;
        
        // 尝试获取不存在的 scheme
        use halo_model::GroupVersionKind;
        let non_existent_gvk = GroupVersionKind {
            group: "non.existent".to_string(),
            version: "v1".to_string(),
            kind: "NonExistent".to_string(),
        };
        
        match scheme_manager.get(&non_existent_gvk) {
            Ok(scheme) => {
                println!("Unexpectedly found scheme: {:?}", scheme);
            }
            Err(e) => {
                println!("Expected error when querying non-existent scheme: {:?}", e);
            }
        }
        
        Ok(())
    }
}

/// 使用说明和最佳实践
/// 
/// ## 关键改进
/// 
/// 1. **内部可变性**: 使用 `RwLock<Vec<Scheme>>` 替代 `Vec<Scheme>`
///    - 允许在 `Arc<SchemeManager>` 中进行可变操作
///    - 支持多线程安全访问
///    - 读操作可以并发，写操作互斥
/// 
/// 2. **方法签名变更**: 
///    - `&mut self` → `&self`
///    - 返回值从引用改为拥有的值（避免生命周期问题）
/// 
/// 3. **错误处理**: 
///    - 所有可能失败的操作都返回 `AppResult<T>`
///    - 锁获取失败会返回适当的错误
/// 
/// ## 使用模式
/// 
/// ```rust
/// // 1. 从依赖注入容器获取服务
/// let scheme_manager = get_scheme_manager!()?;
/// 
/// // 2. 直接调用方法，无需可变引用
/// scheme_manager.register::<MyType>().await?;
/// 
/// // 3. 查询操作
/// let scheme = scheme_manager.get_by_type::<MyType>().await?;
/// ```
/// 
/// ## 性能考虑
/// 
/// - 读操作（查询）可以并发执行
/// - 写操作（注册/注销）会阻塞其他写操作，但不会阻塞读操作
/// - 使用双重检查锁定模式避免不必要的写锁获取
/// 
/// ## 线程安全
/// 
/// - `RwLock` 提供线程安全保证
/// - `Arc` 允许在多个线程间共享 `SchemeManager` 实例
/// - 所有操作都是原子的，不会出现数据竞争
